﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace 装饰模式
{
    class Program
    {
        static void Main(string[] args)
        {
            //ConcreteComponent c = new ConcreteComponent();
            //ConcreteDecoratorA d1 = new ConcreteDecoratorA();
            //ConcreteDecoratorB d2 = new ConcreteDecoratorB();
            //d1.SetComponent(c);
            //d2.SetComponent(d1);
            //d2.Operation();
            DressUp up = new DressUp();

            Console.ReadLine();
        }
    }
    //对象接口类 可以给这些对象动态地添加职责
    abstract class Component
    {
        public abstract void Operation();
    }
    //具体对象 可以给这个对象添加职责
    class ConcreteComponent : Component
    {
        public override void Operation()
        {
            Console.WriteLine("具体对象的操作");
        }
    }
    //装饰抽象类 继承Component从外类来扩展Component类的功能
    abstract class Decorator : Component
    {
        protected Component component;
        public void SetComponent(Component component)
        {
            this.component = component;
        }

        public override void Operation()
        {
            if (component != null)
            {
                component.Operation();
            }
        }
    }

    #region 具体的装饰对象 起到对Component添加职责的作用
    class ConcreteDecoratorA : Decorator
    {
        //本类独有的功能 区别ConcreteDecoratorB
        private string addedState;
        public override void Operation()
        {
            //先执行原Component的Operation(),再执行本类的功能,
            //如addedState,相当于对原Component进行装饰
            base.Operation();
            addedState = "New State";
            Console.WriteLine("具体装饰对象A的操作");
        }
    }

    class ConcreteDecoratorB : Decorator
    {
        public override void Operation()
        {
            base.Operation();
            AddedBehavior();
            Console.WriteLine("具体装饰对象B的操作");
        }

        //本类独有的方法 区别ConcreteDecoratorA
        private void AddedBehavior()
        {
            Console.WriteLine("装饰对象B的独有方法");
        }
    }
    #endregion
}
